<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>OpenVPN Install</title>
  
    <meta name="author" content="jouyouyun">

    <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
    <!--[if lt IE 9]>
      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->

    <!-- Le styles -->
    <link href="/assets/twitter/stylesheets/bootstrap.min.css" type="text/css" rel="stylesheet" media="all">
<link href="/assets/twitter/stylesheets/style.css" type="text/css" rel="stylesheet" media="all">
<link href="/assets/twitter/widgets/google_prettify/stylesheets/twitter-bootstrap.css" type="text/css" rel="stylesheet" media="all">
 

    <!-- Le fav and touch icons -->
  <!-- Update these with your own images
    <link rel="shortcut icon" href="images/favicon.ico">
    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">
    <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
  -->
  </head>

  <body>

    <div class="navbar">
      <div class="navbar-inner">
        <div class="container">
          <a class="brand" href="/">Jouyouyun&#39;s Blog</a>
          <ul class="nav">
            
              


  <li><a href="/archive">Archive</a></li>


            
              


  <li><a href="/tags">Tags</a></li>


            
              


  <li><a href="/categories">Categories</a></li>


            
              


  <li><a href="/about">About Me</a></li>


            
          </ul>
        </div>
      </div>
    </div>

    <div class="container">

      <div class="content">
        <div class="page-header">
  <h1>OpenVPN Install </h1>
</div>

<div class="row">
  <div class="span8">
    <h2>安装所需软件</h2>

<p>Arch: <code>yaourt -S openvpn easy-rsa</code></p>

<h2>生成证书</h2>

<h3>Server 端</h3>

<ul>
<li><p>Copy template file</p>

<pre><code class="language-shell">sudo mkdir -p /etc/openvpn
sudo cp -R /etc/easy-rsa /etc/openvpn
</code></pre></li>

<li><p>Config vars
取消并修改以下项:</p></li>
</ul>

<pre><code class="language-shell">set_var EASYRSA_REQ_COUNTRY     &quot;CN&quot;
set_var EASYRSA_REQ_PROVINCE    &quot;Hongkong&quot;
set_var EASYRSA_REQ_CITY        &quot;Hongkong&quot;
set_var EASYRSA_REQ_ORG         &quot;jouyouyun.info&quot;
set_var EASYRSA_REQ_EMAIL       &quot;wen@jouyouyun.iofn&quot;
set_var EASYRSA_REQ_OU          &quot;Jouyouyun OpenVPN&quot;
</code></pre>

<ul>
<li><p>创建根证书
<code>ca</code> 证书需要输入密码，这个密码是给服务器端和客户端签名时用的</p>

<pre><code class="language-shell">easyrsa init-pki
easyrsa build-ca
</code></pre></li>

<li><p>创建并签名服务器端证书</p></li>
</ul>

<pre><code class="language-shell">easyrsa gen-req &lt;server name&gt; nopass
easyrsa sign server &lt;server name&gt;
</code></pre>

<ul>
<li>创建Diffie-Hellman证书
该证书主要作用是确保共享KEY安全穿越不安全网络</li>
</ul>

<pre><code class="language-shell">easyrsa gen-dh
</code></pre>

<ul>
<li>创建并签名客户端证书</li>
</ul>

<pre><code class="language-shell">easyrsa gen-req &lt;client name&gt; nopass
easyrsa sign client &lt;client name&gt;
</code></pre>

<h2>配置服务器端</h2>

<p>复制一份模板文件(<code>/usr/share/openvpn/examples/server.conf</code>)到 <code>/etc/openvpn</code> 目录, 然后开始修改相关项.</p>

<p>然后将证书文件放在 <code>/etc/openvpn</code> 目录下, 需要的文件包括:</p>

<pre><code class="language-shell">easy-rsa/pki/ca.crt
easy-rsa/pki/dh.pem
easy-rsa/pki/issued/&lt;server name&gt;.crt
easy-rsa/pki/private/&lt;server name&gt;.key
</code></pre>

<h2>配置客户端</h2>

<p>复制一份模板文件 <code>/usr/share/openvpn/examples/client.conf</code>, 然后开始修改相关项.</p>

<p>将以下证书文件与配置文件放在一起, 需要的文件包括:</p>

<pre><code class="language-shell">easy-rsa/pki/ca.crt
easy-rsa/pki/issued/&lt;client name&gt;.crt
easy-rsa/pki/private/&lt;client name&gt;.key
</code></pre>

<h2>开启路由转发</h2>

<pre><code class="language-shell">sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf
sysctl -p
# 允许vpn客户端所在网段流量转发到其它网卡
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
# 将vpn客户端的流量转到eth0，允许vpn客户端上网，即NAT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j  MASQUERADE
</code></pre>

<h2>示例</h2>

<p>认证可以通过证书认证也可以使用用户名密码认证，推荐使用用户名密码认证, 这样方便添加用户.</p>

<h3>证书认证</h3>

<ul>
<li>服务端</li>
</ul>

<pre><code class="language-shell">port 1194
proto tcp
dev tun

ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem

server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /etc/openvpn/ipp.txt
push &quot;redirect-gateway def1 bypass-dhcp&quot;
push &quot;dhcp-option DNS 8.8.8.8&quot;
push &quot;dhcp-option DNS 8.8.4.4&quot;
client-to-client
keepalive 10 120
cipher AES-256-CBC
;comp-lzo # 禁用压缩，如果开启客户端配置中也需要开启
max-clients 100
persist-key
persist-tun

status /var/log/openvpn/openvpn-status.log
log         /var/log/openvpn/openvpn.log
log-append  /var/log/openvpn/openvpn.log
verb 3
</code></pre>

<ul>
<li>客户端</li>
</ul>

<pre><code class="language-shell">client
dev tun
proto tcp

resolv-retry infinite
remote &lt;your vps ip&gt; 1194
nobind

persist-key
persist-tun

ca ca.crt
cert client.crt
key client.key

cipher AES-256-CBC
#comp-lzo
verb 3
</code></pre>

<h3>用户名密码认证</h3>

<p>需要加入auth-user-pass-verify，开启用户密码脚本, 脚本示例, 读取 <code>/etc/openvpn/passwd</code> 文件:</p>

<pre><code class="language-shell">#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman &lt;mathias@openvpn.se&gt;
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.

PASSFILE=&quot;/etc/openvpn/passwd&quot;
LOG_FILE=&quot;/var/log/openvpn/openvpn-password.log&quot;
TIME_STAMP=`date &quot;+%Y-%m-%d %T&quot;`

###########################################################

if [ ! -r &quot;${PASSFILE}&quot; ]; then
  echo &quot;${TIME_STAMP}: Could not open password file \&quot;${PASSFILE}\&quot; for reading.&quot; &gt;&gt; ${LOG_FILE}
  exit 1
fi

CORRECT_PASSWORD=`awk '!/^;/&amp;&amp;!/^#/&amp;&amp;$1==&quot;'${username}'&quot;{print $2;exit}' ${PASSFILE}`

if [ &quot;${CORRECT_PASSWORD}&quot; = &quot;&quot; ]; then
  echo &quot;${TIME_STAMP}: User does not exist: username=\&quot;${username}\&quot;, password=\&quot;${password}\&quot;.&quot; &gt;&gt; ${LOG_FILE}
  exit 1
fi

if [ &quot;${password}&quot; = &quot;${CORRECT_PASSWORD}&quot; ]; then
  echo &quot;${TIME_STAMP}: Successful authentication: username=\&quot;${username}\&quot;.&quot; &gt;&gt; ${LOG_FILE}
  exit 0
fi

echo &quot;${TIME_STAMP}: Incorrect password: username=\&quot;${username}\&quot;, password=\&quot;${password}\&quot;.&quot; &gt;&gt; ${LOG_FILE}
exit 1
</code></pre>

<ul>
<li>服务端</li>
</ul>

<pre><code class="language-shell">port 1194
proto tcp
dev tap

#不要求客户端有证书
client-cert-not-required
username-as-common-name

script-security 3 system
#使用脚本验证密码
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env

ca   /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key  /etc/openvpn/keys/server.key
dh   /etc/openvpn/keys/dh1024.pem

server 10.8.6.0 255.255.255.0

#保存已有的用户和ip的对应关系
ifconfig-pool-persist ipp.txt

#允许客户端之间互访
client-to-client

keepalive 10 120

user nobody
group nogroup

persist-key
persist-tun

#保存日志
status openvpn-status.log
#日志冗余级别
verb 3
</code></pre>

<ul>
<li>客户端</li>
</ul>

<p>客户端配置文件中去掉于证书相关的配置，加入 <code>auth-user-pass</code> 打开用户名密码验证.
可以加入auth-nocache可以在断线后防止内存中保存用户名和密码来提高安全性。</p>

<h2>参考</h2>

<ul>
<li><a href="http://blog.chinaunix.net/uid-24250828-id-3536671.html"> Linux 下OpenVPN 密钥认证 和 用户名/密码认证 笔记</a></li>
</ul>

    <hr>
    <div class="pagination">
      <ul>
        <ul>
          
            <li class="prev"><a href="/Blog/Leanote-Install/" title="Leanote Install">&larr; Previous</a></li>
          
          

            <li><a href="/archive">Archive</a></li>

          
            <li class="next"><a href="/Blog/MIME-Usage/" title="MIME Usage">Next &rarr;</a></li>
          
          
        </ul>
      </ul>
    </div>
    <hr>
    
<div id="disqus_thread"></div>
<script>
    var disqus_developer = 1;
    var disqus_shortname = 'jekyllbootstrap'; // required: replace example with your forum shortname
    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>

  </div>
  
  <div class="span4">
    <h4>Published</h4>
    <div class="date"><span>2016-12-27</span></div>
    <br>
    <h4>Categories</h4>
    <ul class="tag_box">
    
      <li>
  <a href="/categories/#Blog-ref">Blog <span>23</span></a>
</li>
    
    </ul>
    <br>
    <h4>Tags</h4>
    <ul class="tag_box">
    
      <li>
  <a href="/tags/#OpenVPN-ref">OpenVPN <span>1</span></a>
</li>
    
    </ul>
  </div>
</div>

      </div>

      <footer>
        <p>&copy; jouyouyun 2013 
          with help from <a href="http://github.com/wendal/gor" target="_blank" title="Gor -- Fast Blog">Gor</a>
          and <a href="http://twitter.github.com/bootstrap/" target="_blank">Twitter Bootstrap</a>
		  and Idea from <a href="http://ruhoh.com" target="_blank" title="The Definitive Technical Blogging Framework">ruhoh</a>
        </p>
      </footer>

    </div> <!-- /container -->

    
<script src="//cdnjscn.b0.upaiyun.com/libs/prettify/r298/prettify.min.js"></script>
<script>
  var pres = document.getElementsByTagName("pre");
  for (var i=0; i < pres.length; ++i) {
    pres[i].className = "prettyprint linenums";
  }
  prettyPrint();
</script>

    
<script type="text/javascript">

  var _gaq = _gaq || [];
  var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';
  _gaq.push(['_require', 'inpage_linkid', pluginUrl]);
  _gaq.push(['_setAccount', 'UA-123-12']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>
  </body>
</html>
